package spe.ui.view;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.ViewPart;
import org.jbpm.gd.common.model.SemanticElementFactory;

import spe.Activator;
import spe.common.ElementUtil;

import spe.model.spem.MethodLibrary;
import spe.model.spem.MethodPlugin;
import spe.model.spem.SPEMElement;

import spe.ui.action.NewMenuAction;
import spe.ui.action.PropertiesAction;
import spe.ui.treeprovider.MethodLibraryLabelProvider;
import spe.ui.treeprovider.MethodLibraryTreeContentProvider;

public class MethodLibraryView extends ViewPart implements PropertyChangeListener
{
	public static String VIEW_ID = MethodLibraryView.class.getName();
	private TreeViewer treeViewer;

	@Override
	public void createPartControl(Composite parent) 
	{
		createViewer(parent);
		getSite().setSelectionProvider(treeViewer);
		hookDoubleClickCommand();
	}

	@Override
	public void setFocus() 
	{
		treeViewer.getControl().setFocus();
	}

	//To be moved to super class
	public void createViewer(Composite parent)
	{
		treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
		treeViewer.setContentProvider(new MethodLibraryTreeContentProvider());
		treeViewer.setLabelProvider(new MethodLibraryLabelProvider());
		
		List<MethodLibrary> hm = new ArrayList<MethodLibrary>();
		
		//For testing purpose
		//SemanticElementFactory factory = new SemanticElementFactory(this.getSite().getId());
		//MethodLibrary ml = TestClass.createExampleMethodLibrary(factory);
		//ml.addPropertyChangeListener(this);
		//hm.add(ml);
		
		treeViewer.setInput(hm);
		
		MenuManager mnmgr = new MenuManager("#PopupMenu");
		Menu menu = mnmgr.createContextMenu(treeViewer.getControl());
		mnmgr.addMenuListener(new IMenuListener(){
			@Override
			public void menuAboutToShow(IMenuManager manager) {
				if(treeViewer.getSelection().isEmpty())
					return;
				
				if(treeViewer.getSelection() instanceof IStructuredSelection)
				{
					IStructuredSelection selection = (IStructuredSelection)treeViewer.getSelection();
					SPEMElement obj = (SPEMElement)(selection.getFirstElement());
					
					if(obj instanceof MethodLibrary)
					{
						MenuManager mm = new MenuManager("New", Activator.getImageDescriptorByPath("icons/new_con.gif"), "CTX_NEW_MENU");
						mm.add(new NewMenuAction(obj, ElementUtil.METHOD_PLUGIN, getSite().getShell()));
						mm.add(new NewMenuAction(obj, ElementUtil.METHOD_CONFIG, getSite().getShell()));
						manager.add(mm);
					}
					else
					if(obj instanceof MethodPlugin)
					{
						MenuManager mm = new MenuManager("New");
						mm.add(new NewMenuAction(obj, ElementUtil.ACTIVITY, getSite().getShell()));
						mm.add(new NewMenuAction(obj, ElementUtil.ROLE_DEFINITION, getSite().getShell()));
						mm.add(new NewMenuAction(obj, ElementUtil.TASK_DEFINITION, getSite().getShell()));
						mm.add(new NewMenuAction(obj, ElementUtil.GUIDANCE, getSite().getShell()));
						manager.add(mm);
					}
					
					
					manager.add(new PropertiesAction(obj));
				}
				
			}
			
		});
		mnmgr.setRemoveAllWhenShown(true);
		treeViewer.getControl().setMenu(menu);
		getSite().registerContextMenu(mnmgr, treeViewer);
		getSite().setSelectionProvider(treeViewer);
	}
	
	private void hookDoubleClickCommand()
	{
		treeViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class);
				try {
					handlerService.executeCommand("spe.command.openGraphicalEditor", null);
				} catch (Exception ex) 
				{
					ex.printStackTrace();
					throw new RuntimeException("spe.command.openGraphicalEditor not found");
				}
			}
		});
	}
	
	//for testing purpose only
	public void addAndRefresh(MethodLibrary ml)
	{
		MethodLibraryTreeContentProvider mp = (MethodLibraryTreeContentProvider)treeViewer.getContentProvider();
		if(ml != null)
		{
			//!!!! need to add this view into all sub-element as a adapter
			ml.addPropertyChangeListener(this);
			
			mp.addElement(ml);
		}
		//System.out.println("[MethodLibraryTreeView] addAndRefresh " + (ml==null?"null":ml.getName()));
		treeViewer.refresh();
	}	

	@Override
	public void propertyChange(PropertyChangeEvent notification)
	{
		treeViewer.refresh();
	}
}
